/*
 * GraphIntAdjMatrix.c
 *
 *  Created on: 21/01/2012
 *      Author: marcio
 */

char mask[8] = {'a','b','c','d','e','f','g','h'};//TODO fazer isso direito

#define zero 'a'

GraphInt* graphint_newGraph(int n){
	GraphInt* g = malloc(sizeof(Graph));
	g->n = n;
	g->m = 0;
	g->edges = malloc(sizeof(char*)*n);
	int i,j;
	for(i = 0; i < g->n; i ++){
		g->edges[i] = malloc(sizeof(char*)*(n/8 + 1));
		for(j = i+1; j < g->n; j++){
			edge[i][j] = zero;
		}
	}
}

GraphInt* graphint_readGraphInt(FILE* filegraph){
	//TODO
	return NULL;
}

GraphInt* graphint_complement(GraphInt* g){
	GraphInt comp = graphint_newGraph(g->n);
	int i,j;
	for(i = 0; i < g->n; i ++){
		for(j = i+1; j < g->n; j++){
			if(!graphint_hasEdge(g,i,j))graphint_addEdge(comp, i, j);
		}
	}
}

GraphInt* graphint_homophism(GraphInt* g){

}

int graphint_addEdge(GraphInt* g, int v, int u){
	g->edges[v][u/8] = g->edges[v][u/8] || mask[u % 8];
	g->edges[u][v/8] = g->edges[u][v/8] || mask[v % 8];
	return 0;
}

int graphint_deleteEdge(GraphInt* g, int v, int u){
	g->edges[v][u/8] = g->edges[v][u/8] ^ mask[u % 8];
	g->edges[u][v/8] = g->edges[u][v/8] ^ mask[v % 8];
	return 0;}

int graphint_hasEdge(GraphInt* g, int v, int u){
	return g->edges[v][u/8] && mask[u % 8] != zero;
}

int graphint_degree(GraphInt* g, int v){
	int i, degree = 0;
	for(i = 0; i < g->n; i ++){
		if(graphint_hasEdge(g,i,v) && i != v)degree++;
	}
	return degree;
}

int* graphint_getNeigboorhood(GraphInt* g, int v){
	int i, degree = 0;
	int* neig = malloc(sizeof(int*)*graph_degree(g, v));
	for(i = 0; i < g->n; i ++){
		if(graphint_hasEdge(g,i,v) && i != v)neig[degree++] = i;
	}
	return neig;
}

int* graphint_getAntiNeigboorhood(GraphInt* g, int v){
	int i, degree = 0;
	int* antineig = malloc(sizeof(int*)*graph_degree(g, v));
	for(i = 0; i < g->n; i ++){
		if(!graphint_hasEdge(g,i,v) && i != v)antineig[degree++] = i;
	}
	return antineig;
}

void graphint_breathFirstSeacrh(GraphInt* g, int v, void (*action)(int)){
	int end = -1;
	char status[g->n];
	Queue* q = queue_newQueue();
	queue_add(1,vind);
	int i, j, k;
	for(i = 0; i < g->n; i++){
		status[i] = 'n';
	}
	int u;
	status[v] = 'v';
	do{
		u = *(queue_push(q));
		action(u);
		for(i = 0; i < g->n; i++){
			if(graph_hasEdge(g, i, u) && status[i]== 'n'){
				int node = i;
				status[i] = 's';
				queue_add(q,&node);
			}
		}
	}while(!queue_isEmpty(q));
}

void graphint_deepFirstSeacrh(GraphInt* g, int v, void (*action)(int)){
	int end = -1;
	char status[g->n];
	Stack* s = stack_newStack();
	stack_add(s,vind);
	int i, j, k;
	for(i = 0; i < g->n; i++){
		status[i] = 'n';
	}
	int u;
	status[v] = 'v';
	do{
		u = *(stack_push(s));
		action(u);
		for(i = 0; i < g->n; i++){
			if(graph_hasEdge(g, i, u) && status[i]== 'n'){
				int node = i;
				status[i] = 's';
				stack_add(s,&node);
			}
		}
	}while(!stack_isEmpty(s));
}

int* graphint_getNodes(GraphInt* g){
	int* vertex = malloc(sizeof(int)*g->n);
	int i;
	for(i = 0; i < g->n; i++){
		vertex[i] = i;
	}
	return vertex;
}
